﻿//
//
// 版权所有 (c) 2021-2023 JR  
//
// 特此免费授予获得本软件的任何人以处理本软件的权利，但须遵守以下条件：在所有副本或重要部分的软件中必须包括上述版权声明和本许可声明。
//
// 软件按“原样”提供，不提供任何形式的明示或暗示的保证，包括但不限于对适销性、适用性和非侵权的保证。
// 在任何情况下，作者或版权持有人均不对任何索赔、损害或其他责任负责，无论是因合同、侵权或其他方式引起的，与软件或其使用或其他交易有关。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EMC.VISITOR.Core;
public static class DataConvertList
{
    /// <summary>
    /// 只轉換一層的實體類對象，實體類中的實體類不參與轉換了
    /// </summary>
    /// <param name="dt"></param>
    /// <returns></returns>
    public static List<T> DataTableConvertToList<T>(this DataTable dt) where T : new()
    {
        // 定义集合  
        List<T> ts = new List<T>();

        // 获得此模型的类型  
        Type type = typeof(T);
        //定义一个临时变量  
        string tempName = string.Empty;
        //遍历DataTable中所有的数据行  
        foreach (DataRow dr in dt.Rows)
        {
            T t = new T();
            // 获得此模型的公共属性  
            PropertyInfo[] propertys = t.GetType().GetProperties();
            //遍历该对象的所有属性  
            foreach (PropertyInfo pi in propertys)
            {
                try
                {

                    ModelType modelType = GetModelType(pi.PropertyType);
                    if (modelType == ModelType.Else)//引用类型
                    {
                        Assembly assembly = Assembly.GetExecutingAssembly(); // 获取当前程序集
                        var obj = assembly.CreateInstance(pi.PropertyType.FullName); // 创建类的实例，返回为 object 类型，需要强制类型转换
                                                                                     //引用类型 必须对泛型实例化
                        PropertyInfo[] _propertys = obj.GetType().GetProperties();
                        setPropertyData(_propertys, obj, dt, dr);

                        pi.SetValue(t, obj, null);
                        continue;
                    }
                    tempName = pi.Name;//将属性名称赋值给临时变量  
                                       //检查DataTable是否包含此列（列名==对象的属性名）    
                                       //if (dt.Columns.ContainsKey(tempName))
                    if (dt.Columns.Contains(tempName))
                    {
                        // 判断此属性是否有Setter  
                        if (!pi.CanWrite) continue;//该属性不可写，直接跳出  
                                                   //取值  
                        object value = dr[tempName];
                        //如果非空，则赋给对象的属性  
                        if (value != DBNull.Value)
                            pi.SetValue(t, value, null);
                    }
                }
                catch (Exception e)
                {
                    throw new Exception(e.Message);
                }

            }
            //对象添加到泛型集合中  
            ts.Add(t);
        }
        return ts;
    }

    /// <summary>
    /// 設置第二層的對象
    /// </summary>
    /// <param name="propertys"></param>
    /// <param name="t"></param>
    /// <param name="dt"></param>
    /// <param name="dr"></param>
    private static void setPropertyData(PropertyInfo[] propertys, object t, DataTable dt, DataRow dr)
    {
        string tempName = string.Empty;
        foreach (PropertyInfo pi in propertys)
        {
            try
            {

                ModelType modelType = GetModelType(pi.PropertyType);
                if (modelType == ModelType.Else)//引用类型
                {
                    continue;
                }
                tempName = pi.Name;//将属性名称赋值给临时变量  
                                   //检查DataTable是否包含此列（列名==对象的属性名）    
                                   //if (dt.Columns.ContainsKey(tempName))
                if (dt.Columns.Contains(tempName))
                {
                    // 判断此属性是否有Setter  
                    if (!pi.CanWrite) continue;//该属性不可写，直接跳出  
                                               //取值  
                    object value = dr[tempName];
                    //如果非空，则赋给对象的属性  
                    if (value != DBNull.Value)
                        pi.SetValue(t, value, null);
                }
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }

        }
    }

    /// <summary>
    /// 类型枚举
    /// </summary>
    private enum ModelType
    {
        //值类型
        Struct,
        Enum,
        //引用类型
        String,
        Object,
        Else
    }

    private static ModelType GetModelType(Type modelType)
    {
        //值类型
        if (modelType.IsEnum)
        {
            return ModelType.Enum;
        }
        //值类型
        if (modelType.IsValueType)
        {
            return ModelType.Struct;
        }
        //引用类型 特殊类型处理,c#对string也当做值类型处理
        if (modelType == typeof(string))
        {
            return ModelType.String;
        }
        //引用类型 特殊类型处理
        return modelType == typeof(object) ? ModelType.Object : ModelType.Else;
    }





}

